package com.example.baselibrary.image;

import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.example.baselibrary.R;
import com.example.baselibrary.commonutil.PictureUriUtil;
import com.example.baselibrary.permission.PermissionCheck;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import top.zibin.luban.OnCompressListener;

import java.io.File;
import java.util.List;

import static android.app.Activity.RESULT_OK;

public class PhotoPicker extends Fragment {

    private static final int PHOTO_WAY_TAKE = 0;
    private static final int PHOTO_WAY_ALBUM = 1;

    private static final int REQUEST_CODE_TAKE = 0x1FFF;
    private static final int REQUEST_CODE_ALBUM = 0x2FFF;

    private static final String CACHE_DIR_NAME = "PhotoCache";

    private QMUIDialog pickerDialog;

    private String fileProviderAuthorities;

    private String tempPhotoPath;
    private String photoUrl;

    private boolean compress;

    private Uri photoUri;
    private File cameraTempFile;

    private boolean needPhotoForResult = false;

    private OnPickListener onPickListener;

    public void setOnPickListener(@Nullable OnPickListener listener) {
        this.onPickListener = listener;
    }

    public OnPickListener getOnPickListener() {
        return onPickListener;
    }

    public void setTempPhotoPath(String path) {
        this.tempPhotoPath = path;
    }

    public String getTempPhotoPath() {
        return tempPhotoPath;
    }

    public void setCompress(boolean compress) {
        this.compress = compress;
    }

    public boolean getCompress() {
        return compress;
    }

    public void setFileProviderAuthorities(String fileProviderAuthorities) {
        this.fileProviderAuthorities = fileProviderAuthorities;
    }

    public String getFileProviderAuthorities() {
        return fileProviderAuthorities;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (pickerDialog == null) {
            setupPickerDialog();
        }
        pickerDialog.show();
    }

    private void setupPickerDialog() {
        String[] getPhotoWays = getResources().getStringArray(R.array.get_photo_way);
        pickerDialog = new QMUIDialog.MenuDialogBuilder(getActivity()).addItems(
                getPhotoWays, (dialog, which) -> {
                    switch (which) {
                        case PHOTO_WAY_TAKE:
                            getPhotoFromCamera();
                            needPhotoForResult = true;
                            break;
                        case PHOTO_WAY_ALBUM:
                            getPhotoFromAlbum();
                            needPhotoForResult = true;
                            break;
                    }
                    dialog.dismiss();
                }
        ).create(com.qmuiteam.qmui.R.style.QMUI_Dialog);
        pickerDialog.setCanceledOnTouchOutside(true);
        pickerDialog.setOnDismissListener(dialog -> {
            if (!needPhotoForResult) {
                dismiss();
            }
        });
    }

    @PermissionCheck(permission = Manifest.permission.CAMERA)
    private void getPhotoFromCamera() {
        cameraTempFile = new File(tempPhotoPath);
        if (Build.VERSION.SDK_INT >= 24) {
            if (TextUtils.isEmpty(fileProviderAuthorities)) {
                throw new IllegalArgumentException("please config your file provider authorities first while " +
                        "SDK higher than 24");
            }
            photoUri = FileProvider.getUriForFile(getActivity(), fileProviderAuthorities, cameraTempFile);
        } else {
            photoUri = Uri.fromFile(cameraTempFile);
        }
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        startActivityForResult(intent, REQUEST_CODE_TAKE);
    }

    @PermissionCheck(permission = Manifest.permission.WRITE_EXTERNAL_STORAGE)
    private void getPhotoFromAlbum() {
        MatisseManager.start(this, REQUEST_CODE_ALBUM, 1);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_TAKE:
                if (resultCode == RESULT_OK) {
                    photoUrl = cameraTempFile.getAbsolutePath();
                    handleResultPhoto();
                } else {
                    dismiss();
                }
                break;
            case REQUEST_CODE_ALBUM:
                if (resultCode == RESULT_OK) {
                    List<Uri> photoList = MatisseManager.obtainResult(data);
                    List<String> photoPathList = PictureUriUtil.handleImageAfterKitKat(getActivity(), photoList);
                    photoUrl = photoPathList.get(0);
                    handleResultPhoto();
                } else {
                    dismiss();
                }
                break;
        }
    }

    private void handleResultPhoto() {
        if (compress) {
            String cacheDirPath = getActivity().getExternalCacheDir().getAbsolutePath() +
                    File.separator + CACHE_DIR_NAME;
            File cacheFile = new File(cacheDirPath);
            if (!cacheFile.exists()) {
                cacheFile.mkdirs();
            }
            LubanUtil.compress(getActivity(), photoUrl, cacheDirPath, new OnCompressListener() {
                @Override
                public void onStart() {

                }

                @Override
                public void onSuccess(File file) {
                    dismiss();
                    if (onPickListener != null) {
                        onPickListener.onPickComplete(file.getAbsolutePath());
                    }
                }

                @Override
                public void onError(Throwable e) {
                    dismiss();
                }
            });
        } else {
            if (onPickListener != null) {
                onPickListener.onPickComplete(photoUrl);
            }
            dismiss();
        }
    }

    private void dismiss() {
        pickerDialog.setOnDismissListener(null);
        FragmentTransaction transaction = requireFragmentManager().beginTransaction();
        transaction.remove(this);
        transaction.commit();
    }

    public void show(FragmentManager fragmentManager, String tag) {
        fragmentManager.beginTransaction().add(this, tag).commit();
    }

    public String createTag() {
        return toString();
    }

    public interface OnPickListener {

        void onPickComplete(String photoUrl);
    }
}
